package common.server.redis.jedis;

import java.util.List;
import java.util.Map;
import java.util.Set;

import common.server.redis.AbstractRedisResource;
import common.server.utils.JsonUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCommands;

/**
 * JEDIS操作
 * 
 * @author Administrator
 * @version [版本号, 2017/11/22 0022]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class JedisResource extends AbstractRedisResource<JedisCommands> {

	private final Jedis jedis;

	public JedisResource(Jedis jedis) {
		this.jedis = jedis;
	}

	@Override
	public <T> T get(String key, Class<T> clazz) {
		return 	call((jedis)->{
			String value = jedis.get(key);
			if (value == null) {
				return null;
			}
			if (clazz == String.class) {
				return (T) value;
			}
			return JsonUtils.fromJson(value, clazz);
		});


	}

	@Override
	public <T> T hget(String key, String field, Class<T> clazz) {
		return 	call((jedis)->{
			String value = jedis.hget(key, field);
			if (value == null) {
				return null;
			}
			if (clazz == String.class) {
				return (T) value;
			}

			return JsonUtils.fromJson(value, clazz);
		});

	}

	@Override
	public Map<String, String> hgetAll(String key) {
		return 	call((jedis)->{
			return jedis.hgetAll(key);
		});

	}


	@Override
	public Set<String> hkeys(String key) {
		return 	call((jedis)->{
			return jedis.hkeys(key);
		});

	}

	@Override
	public <T> List<T> hmget(String key, Class<T> clazz, String... fields) {
		return 	call((jedis)->{
			List<String> value = jedis.hmget(key, fields);
			return toList(value, clazz);
		});

	}

	@Override
	public <T> T lpop(String key, Class<T> clazz) {
		return 	call((jedis)->{
			String value = jedis.lpop(key);
			if (value == null) {
				return null;
			}
			if (clazz == String.class) {
				return (T) value;
			}
			return JsonUtils.fromJson(value, clazz);
		});


	}

	@Override
	public <T> T rpop(String key, Class<T> clazz) {
		return 	call((jedis)->{
			String value = jedis.rpop(key);
			if (value == null) {
				return null;
			}
			if (clazz == String.class) {
				return (T) value;
			}
			return JsonUtils.fromJson(value, clazz);
		});


	}

	@Override
	public List<String> lrange(String key, int start, int end) {
		return 	call((jedis)->{
			List<String> value = jedis.lrange(key, start, end);
			return value;
		});
	}

	@Override
	public long llen(String key) {
		return 	call((jedis)->{
			return jedis.llen(key);
		});
	}

	@Override
	public <T> List<T> zrange(String key, int start, int end, Class<T> clazz) {
		return 	call((jedis)->{
			Set<String> value = jedis.zrange(key, start, end);
			return toList(value, clazz);
		});
	}

	/**
	 * 设置K-V
	 * 
	 * @param key
	 * @param value
	 * @param time
	 */
	@Override
	public void set(String key, String value, long time) {
		call((jedis)->{
				jedis.set(key, value);
				if (time > 0) {
					jedis.pexpire(key, time);
				}
				return null;
		});
	}

	/**
	 * 设置K-V
	 * 
	 * @param key
	 * @param value
	 * @param time
	 */
	@Override
	public Long setnx(String key, String value, long time) {
		
		return call((jedis)->{
			Long setnxValue = jedis.setnx(key, value);
			if (time > 0) {
				jedis.pexpire(key, time);
			}
			return setnxValue;
		});
		
	}
	
	@Override
	public void del(String key) {
		call((jedis)->{
			jedis.del(key);
			return null;
		});
	}

	@Override
	public void hset(String key, String field, String value, long time) {
		call((jedis)->{
			jedis.hset(key, field, value);
			if (time > 0) {
				jedis.pexpire(key, time);
			}
			return null;
		});
	}
	
	@Override
	public Long hincrby(String key, String field) {

		return call((jedis) -> {
			Long value = jedis.hincrBy(key, field, 1L);
			return value;
		});
	}

	@Override
	public void hdel(String key, String field) {

		call((jedis)->{
			jedis.hdel(key, field);
			return null;
		});
	}



	@Override
	public void hmset(String key, Map<String, String> hash, long time) {
		call((jedis)->{
			jedis.hmset(key, hash);
			if (time > 0) {
				jedis.pexpire(key, time);
			}
			return null;
		});
	}

	@Override
	public void lpush(String key, String... value) {
		call((jedis)->{
			jedis.lpush(key, value);
			return null;
		});
	}


	@Override
	public void rpush(String key, String value) {
		call((jedis)->{
			jedis.rpush(key, value);
			return null;
		});
	}


	@Override
	public void expire(String key, long time) {
		call((jedis)->{
			jedis.pexpire(key, time);
			return null;
		});
	}
	
	@Override
	public void sadd(String key, String...value) {
		call((jedis)->{
			jedis.sadd(key, value);
			return null;
		});
	}
	
	@Override
	public JedisCommands getRealResource() {
		return jedis;
	}

	@Override
	public void close() {
        if(this.jedis != null){
        	try {
				this.jedis.close();
			}catch (Throwable e){
        		//防御行容错
			}
		}
	}


}
